package com.sztu.service;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.sztu.mapper.DeviceMapper;
import com.sztu.mapper.DeviceStateMapper;
import com.sztu.mapper.DeviceTypeMapper;
import com.sztu.pojo.Device;
import com.sztu.pojo.DeviceState;
import com.sztu.pojo.DeviceType;
import com.sztu.pojo.Student;
import com.sztu.utils.LongUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DeviceServiceImpl implements DeviceService{

    private final DeviceTypeMapper deviceTypeMapper;

    private final DeviceMapper deviceMapper;

    private final ShiroUserService shiroUserService;

    private final RoomService roomService;

    private final DeviceStateMapper deviceStateMapper;

    public DeviceServiceImpl(DeviceTypeMapper deviceTypeMapper, DeviceMapper deviceMapper, ShiroUserService shiroUserService, RoomService roomService, DeviceStateMapper deviceStateMapper) {
        this.deviceTypeMapper = deviceTypeMapper;
        this.deviceMapper = deviceMapper;
        this.shiroUserService = shiroUserService;
        this.roomService = roomService;
        this.deviceStateMapper = deviceStateMapper;
    }


    private Map<String,Object> getDeviceTypeInfoById(Long id){
        DeviceType deviceType=deviceTypeMapper.selectById(id);
        Map<String,Object> deviceTypeInfo=new HashMap<>();
        deviceTypeInfo.put("device_type_name",deviceType.getTypeName());
        deviceTypeInfo.put("device_type_description",deviceType.getDescription());
        return deviceTypeInfo;
    }

    private Map<String,Object> getDeviceStateInfoById(Long id){
        DeviceState deviceState=deviceStateMapper.selectById(id);
        Map<String,Object> deviceStateInfo=new HashMap<>();
        deviceStateInfo.put("device_state_name",deviceState.getStateName());
        deviceStateInfo.put("device_state_description",deviceState.getDescription());
        return deviceStateInfo;
    }



    @Override
    public List<DeviceType> getDeviceType() {
        return deviceTypeMapper.selectList(null);
    }

    @Override
    public void updateDeviceTypeByMap(Map<String,Object> map) {
        deviceTypeMapper.updateById(generateDeviceTypeByMap(map).setId(Long.parseLong(map.get("id").toString())));
    }

    @Override
    public void addDeviceType(Map<String,Object> map) {
        deviceTypeMapper.insertByMap(map);
    }

    @Override
    public void deleteDeviceTypeByList(List<String> idList) {
        List<Long> longIdList=idList.stream().map(s -> {
            return Long.parseLong(s);
        }).collect(Collectors.toList());
        deviceTypeMapper.deleteBatchIds(longIdList);
    }

    @Override
    public List<Map<String,Object>> getDevice() {
        List<Map<String,Object>> devices=deviceMapper.selectMaps(null);
        return devices;
    }

    @Override
    public void updateDeviceByMap(Map<String, Object> map) {
        deviceMapper.updateById(generateDeviceByMap(map).setId(Long.parseLong(map.get("id").toString())));
    }

    @Override
    public void addDevice(Map<String, Object> map) {
        deviceMapper.insertByMap(map);
    }

    @Override
    public void deleteDeviceByList(List<String> idList) {
        List<Long> longIdList=idList.stream().map(s -> {
            return Long.parseLong(s);
        }).collect(Collectors.toList());
        deviceMapper.deleteBatchIds(longIdList);
    }

    @Override
    public List<DeviceState> getDeviceState() {
        return deviceStateMapper.selectList(null);
    }

    @Override
    public void updateDeviceStateByMap(Map<String, Object> map) {
        deviceStateMapper.updateById(generateDeviceStateByMap(map).setId(Long.parseLong(map.get("id").toString())));
    }

    @Override
    public void addDeviceState(Map<String, Object> map) {
        deviceStateMapper.insertByMap(map);
    }

    @Override
    public void deleteDeviceStateByList(List<String> idList) {
        List<Long> longIdList=idList.stream().map(s -> {
            return Long.parseLong(s);
        }).collect(Collectors.toList());
        deviceStateMapper.deleteBatchIds(longIdList);
    }

    @Override
    public List<Map<String, Object>> getDeviceInfo() {
        return deviceMapper.getDeviceInfo();
    }

    @Override
    public Boolean canBeBorrowed(Long deviceId) {
        Device device=deviceMapper.selectById(deviceId);
        if(device.getDeviceStateId()!=4L) return false;
        return true;
    }

    @Override
    public void setDeviceState(Long deviceId, Long stateId) {
        Device device=new Device().setId(deviceId).setDeviceStateId(stateId);
        deviceMapper.updateById(device);
    }

    @Override
    public Integer importExcel(File file) {
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        List<Map<String,Object>> dataList = ExcelImportUtil.importExcel(file, Map.class, params);
        for (Map<String,Object> data:dataList){
            try {
                if(deviceMapper.updateById(generateDeviceByExcelMap(data))!=1){
                    deviceMapper.insert(generateDeviceByExcelMap(data));
                }
            }catch (Exception e){
                return 0;
            }
        }
        return 1;
    }

    @Override
    public Workbook exportExcel() {
        List<Map<String,Object>> dataList=deviceMapper.selectMaps(null);
        return ExcelExportUtil.exportExcel(new ExportParams("设备表", "设备"), getBeanEntity() ,
                dataList);
    }

    // excel 的 map映射
    private List<ExcelExportEntity> getBeanEntity() {
        List<ExcelExportEntity> beanEntry=new ArrayList<>();
        beanEntry.add(new ExcelExportEntity("设备id","id"));
        beanEntry.add(new ExcelExportEntity("设备名称","device_name"));
        beanEntry.add(new ExcelExportEntity("设备型号","device_model"));
        beanEntry.add(new ExcelExportEntity("描述","description"));
        beanEntry.add(new ExcelExportEntity("服务厂商","service_company"));
        return beanEntry;
    }

    private Device generateDeviceByExcelMap(Map<String,Object>map){
        return new Device()
                .setDescription((String) map.getOrDefault("描述",null))
                .setDeviceModel((String) map.getOrDefault("设备型号",null))
                .setDeviceName((String)map.getOrDefault("设备名称",null))
                .setServiceCompany((String) map.getOrDefault("服务厂商",null))
                .setId(LongUtil.parseLong(map.getOrDefault("设备id",0L)))
                //还需要设置使用时间暂不进行处理，因为需要装换
                ;
    }

    private DeviceType generateDeviceTypeByMap(Map<String,Object> map){
        return new DeviceType()
                .setDescription((String) map.getOrDefault("description",null))
                .setTypeName((String) map.getOrDefault("typeName",null));
    }

    private Device generateDeviceByMap(Map<String,Object> map){

        return new Device()
                .setDescription((String) map.getOrDefault("description",null))
                .setPrincipalId(LongUtil.parseLong( map.getOrDefault("principal_id",null)))
                .setDeviceModel((String) map.getOrDefault("device_model",null))
                .setDeviceName((String)map.getOrDefault("device_name",null))
                .setDeviceRoomId(LongUtil.parseLong(map.getOrDefault("device_room_id",null)))
                .setDeviceStateId(LongUtil.parseLong(map.getOrDefault("device_state_id",null)))
                .setDeviceTypeId(LongUtil.parseLong( map.getOrDefault("device_type_id",null)))
                .setServiceCompany((String) map.getOrDefault("service_company",null))
                //还需要设置使用时间暂不进行处理，因为需要装换
                ;

    }

    private DeviceState generateDeviceStateByMap(Map<String,Object> map){
        return new DeviceState()
                .setDescription((String) map.getOrDefault("description",null))
                .setStateName((String) map.getOrDefault("stateName",null));
    }
}
